package com.selenium.core.functionlibrary;

import java.io.IOException;
import java.util.UUID;

import org.fest.swing.image.ScreenshotTaker;
import org.testng.Reporter;

import com.selenium.core.SelTestCase;
import com.thoughtworks.selenium.SeleniumException;

/**
 * Provides exception handling to selenium methods.
 * 
 * @author tbhadauria
 *
 */
public class SafeSelenium extends SelTestCase {

	private static ScreenshotTaker screenshotTaker = new ScreenshotTaker();;
	private static String  failureImageFolder = "/reportng/failureimages/";
	
	
	/**
	 * Returns image file path for failure images
	 * 
	 * @param elementLocator	HTML Identifier of object
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @return imageFilePath
	 */
	public String getImageFilePath (String elementLocator, String webObject) {
		
		String imageFilePath = null;
		
		try {
			imageFilePath = new StringBuilder(new java.io.File(".").getCanonicalPath())
			.append(failureImageFolder).append(this.getClass().getName())
			.append(webObject).append(elementLocator)
			.append(UUID.randomUUID()).append(".png").toString();
			
		} catch (IOException e) {			
			Reporter.log(e.getMessage());
		}		
		return imageFilePath;		
	}
	
	public StringBuilder getErrorMessage (String webObject, SeleniumException se) {
		
		StringBuilder errorMessage = null;
		
		try {
			
			errorMessage = new StringBuilder("<span style=\"background: pink; color:blue;\">")
			.append(webObject).append(" is not available.") 
			.append(se.getMessage()).append("</span> ");
			
		} catch (Exception fe) {			
			Reporter.log(fe.getMessage());			
		}		
		return errorMessage;		
	}


	/**
	 * Types in text box. 
	 * Exception is raised in test report if element locator is not found.
	 * 
	 * @param textBoxLocator	Text box locator
	 * @param testData	Data to be keyed in	
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @param logMessage Boolean flag to determine logging
	 */
	public void safeType(String textBoxLocator, String testData, String 
			webObject, boolean logMessage) { 

		// Path for image for failed selenium commands.
		String imageFilePath = getImageFilePath(textBoxLocator, webObject);
		
		try {						
			// Type in text box.
			LogSelenium.type(textBoxLocator, testData, webObject, logMessage);			

		} catch (SeleniumException se) {			
			// Prepare error message.
			StringBuilder errorMsessage = 
				getErrorMessage(webObject, se);					

			try {				
				// Capture Desktop screen shot.
				screenshotTaker.saveDesktopAsPng (imageFilePath);

				// Add screen shot to error message.
				errorMsessage.append("<a href=file:///")
				.append(imageFilePath).append(">ScreenShot</a> <br>" );

			} catch (Exception fe) {

				// Report failure of screen shot capture.
				Reporter.log(fe.getMessage());
			}

			// Log failure in test report along with screen shot when type operation was unsuccessful.
			Reporter.log(errorMsessage.toString());
		}
	}
	
	/**
	 * Checks checkbox or radio button.
	 * Exception is raised in test report if element locator is not found.
	 * 
	 * @param elementLocator Element Locator for check box/radio button
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @param logMessage Boolean flag to determine logging	
	 */
	public void safeCheck(String elementLocator, String webObject, 
			boolean logMessage) {
		
		// Path for image for failed selenium commands.
		String imageFilePath = getImageFilePath(elementLocator, webObject);

		try {						
			// Check the element.
			LogSelenium.check(elementLocator, webObject, logMessage);			

		} catch (SeleniumException se) {			
			// Prepare error message.
			StringBuilder errorMsessage = 
				getErrorMessage(webObject, se);					
			
			try {				
				// Capture Desktop screen shot.
				screenshotTaker.saveDesktopAsPng (imageFilePath);

				// Add screen shot to error message.
				errorMsessage.append("<a href=file:///")
				.append(imageFilePath).append(">ScreenShot</a> <br>" );

			} catch (Exception fe) {

				// Report failure of screen shot capture.
				Reporter.log(fe.getMessage());
			}

			// Log failure in test report along with screen shot when type operation was unsuccessful.
			Reporter.log(errorMsessage.toString());
		}				
	}
	
	/**
	 * Clicks on a button, image or any other html object.
	 * Exception is raised in test report if element locator is not found.
	 * 
	 * @param elementLocator Element Locator for object
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @param logMessage Boolean flag to determine logging	
	 */
	public void safeClick(String elementLocator, String webObject, 
			boolean logMessage) {
		
		// Path for image for failed selenium commands.
		String imageFilePath = getImageFilePath(elementLocator, webObject);

		try {						
			// Check the element.
			LogSelenium.click(elementLocator, webObject, logMessage);			

		} catch (SeleniumException se) {			
			// Prepare error message.
			StringBuilder errorMsessage = 
				getErrorMessage(webObject, se);					
			
			try {				
				// Capture Desktop screen shot.
				screenshotTaker.saveDesktopAsPng (imageFilePath);

				// Add screen shot to error message.
				errorMsessage.append("<a href=file:///")
				.append(imageFilePath).append(">ScreenShot</a> <br>" );

			} catch (Exception fe) {

				// Report failure of screen shot capture.
				Reporter.log(fe.getMessage());
			}

			// Log failure in test report along with screen shot when type operation was unsuccessful.
			Reporter.log(errorMsessage.toString());
		}				
	}
	
	/**
	 * Selects drop down value 
	 * Exception is raised in test report if element locator is not found.
	 * 
	 * @param dropDownLocator	Text box locator
	 * @param testData	Data to be keyed in	
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @param logMessage Boolean flag to determine logging
	 */
	public void safeSelect(String dropDownLocator, String testData, String 
			webObject, boolean logMessage) { 

		// Path for image for failed selenium commands.
		String imageFilePath = getImageFilePath(dropDownLocator, webObject);
		
		try {						
			// Type in text box.
			LogSelenium.select(dropDownLocator, testData, webObject, logMessage);			

		} catch (SeleniumException se) {			
			// Prepare error message.
			StringBuilder errorMsessage = 
				getErrorMessage(webObject, se);					

			try {				
				// Capture Desktop screen shot.
				screenshotTaker.saveDesktopAsPng (imageFilePath);

				// Add screen shot to error message.
				errorMsessage.append("<a href=file:///")
				.append(imageFilePath).append(">ScreenShot</a> <br>" );

			} catch (Exception fe) {

				// Report failure of screen shot capture.
				Reporter.log(fe.getMessage());
			}

			// Log failure in test report along with screen shot when type operation was unsuccessful.
			Reporter.log(errorMsessage.toString());
		}
	}
	
	/**
	 * Provides all drop down values of a drop down
	 * Exception is raised in test report if element locator is not found.
	 * 
	 * @param elementLocator Element Locator for object
	 * @param webObject	User Identifier for object Should <b>NOT</b> contain spaces
	 * @param logMessage Boolean flag to determine logging	
	 */
	public void safeGetSelectOptions(String elementLocator, String webObject, 
			boolean logMessage) {
		
		// Path for image for failed selenium commands.
		String imageFilePath = getImageFilePath(elementLocator, webObject);

		try {						
			// Check the element.
			LogSelenium.getSelectOptions(elementLocator, webObject, logMessage);			

		} catch (SeleniumException se) {			
			// Prepare error message.
			StringBuilder errorMsessage = 
				getErrorMessage(webObject, se);					
			
			try {				
				// Capture Desktop screen shot.
				screenshotTaker.saveDesktopAsPng (imageFilePath);

				// Add screen shot to error message.
				errorMsessage.append("<a href=file:///")
				.append(imageFilePath).append(">ScreenShot</a> <br>" );

			} catch (Exception fe) {

				// Report failure of screen shot capture.
				Reporter.log(fe.getMessage());
			}

			// Log failure in test report along with screen shot when type operation was unsuccessful.
			Reporter.log(errorMsessage.toString());
		}				
	}
}